/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jeff.springWebTestNG.tx;

import com.jeff.springWebTestNG.SpringContextPovider;
import java.util.concurrent.Executor;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronizationManager;

/**
 *
 * @author zhou.zhefu
 */
@Component("applicationEventMulticaster")
public class TransactionAwareApplicationEventMulticaster extends SimpleApplicationEventMulticaster {

    @Override
    public void multicastEvent(ApplicationEvent event) {
        System.out.println("Start Multicasting event=" + event.toString());
        super.multicastEvent(event);
        
        if (event instanceof TransactionAwareEvent && 
                TransactionSynchronizationManager.isSynchronizationActive()) {
            System.out.println("ready to register custom synchronization");
            for (ApplicationListener listener : getApplicationListeners(event)) {
                System.out.println("ok, found tx listeners");
                notifyEvent(listener, event);
            }
        } else {
            super.multicastEvent(event);
        }
        
    }
    
    void notifyEvent(final ApplicationListener listener, final ApplicationEvent event) {
        Executor executor = SpringContextPovider.getApplicationContext().getBean("myTaskExecutor", Executor.class);
        if (executor != null) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Time=" + System.currentTimeMillis() + "; onApplicationEvent() with executor");
                    listener.onApplicationEvent(event);
                }
            });
        } else {
            System.out.println("onApplicationEvent() without executor");
            listener.onApplicationEvent(event);
        }
     }
    
    
}
